<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
    * symbol set 和map 都是 es6的内容
    *
    * Symbol：基本数据类型之一
    *
    * 数值 字符串 布尔值 undefined null 对象 symbol
    *
    * Symbol 唯一标识符
    *   特点：任何两个symbol都是不相等的
    *
    *   能够保证我们的值是唯一的
    *
    *   可以作为属性名存在：就可以保证属性的私有
    *
    * */
    function getObj(){ //这是一个函数作用域 无法从外部直接访问内部属性与变量
        let s1 = Symbol("1")
        let s2 = Symbol("1")
        //console.log(s1 === s2)
        let obj = {}
        obj[s1] = "value"
        return {
            obj:obj,
            getKey:function (key){ //"传入密码"
                if(key === "asd"){ //如果密码相同，返回s1的值
                    return s1
                }else{
                    return
                }
            }
        }
    }

    let o = getObj()


    //如果不能访问这个s1变量，能不能访问出“value”的值?  不能

    /*
    * 假设有一百万人的团队：
    *   每个人都在给o添加属性删除属性，肯定会有很大概率重复，所以可以使用Symbol，可以保证不会有重复相同的情况
    *
    * */

    /*
    * Symbol的两种方法：
    *
    * Symbol.for:
    *   有一个判断，如果之前已经用Symbol.for生成过Symbol，那么下次用Symbol.for就会返回第一次生成的Symbol，怎么判断是否生成过Symbol？
    *   只需要看Symbol.for(值)括号里面的值是否相同
    *
    * Symbol.keyFor
    *
    * */

    let s0 = Symbol("a") //只要是通过Symbol生成的值，绝对是唯一的。唯一的是Symbol，而不是变量s0

    let s1 = Symbol.for("a")

    let s2 = Symbol.for("a")

    let s3 = Symbol.for("b")

    console.log(s0 === s1,s1 === s2,s1 === s3)

    let s4 = s0 //这是赋值，将s0的值赋值给s4，所以它俩值相等

    console.log(s0 === s4)

    let ss1 = Symbol.for({}) //这里面只能传数值和字符串，传入其他会调用隐式类型转换toString方法
    let ss2 = Symbol.for({})

    console.log(ss1 === s2) //true

    //Symbol.keyFor 传入一个Symbol（用Symbol.for生成的，而不是用Symbol生成的） 返回它的 字符串描述
    console.log(Symbol.keyFor(s0)) //打印undefined，因为s0是Symbol生成的，无法访问
    console.log(a = Symbol.keyFor(s1)) //打印s1的值a，s1是Symbol.for生成的
    let sss = Symbol.for(a)

    console.log(sss === s1) //true sss的值就是a的值，a的值就是s1的值，所以sss === s1

    //Symbol 和 Symbol.for 的关系：Symbol（绝对防御） Symbol.for（相对防御）

    /*
    * 什么是Symbol？有什么用？
    *   可以生成唯一的值的数据结构，保证属性的私有性
    *
    * 怎么保证属性的私有性？
    *   1.用函数的闭包保存私有的变量，变量的值是Symbol
    *   2.返回用Symbol加工过的对象
    *   3.通过返回一个函数，校验使用者是否安全，选择性地返回Symbol
    *
    * */



</script>
</body>
</html>